const { execSync } = require('child_process')
const path = require('path')
const fs = require('fs-extra')
const standardVersion = require('standard-version')
const colors = require('picocolors')
const { Project, upload, preview } = require('miniprogram-ci')
const dotenv = require('dotenv')

dotenv.config()

// 此处定义，因为开发的时候会乱搞
const DEV_SERVER_API = 'https://saas.police.mixwoo.com/v2_java'
const PROD_SERVER_API = 'https://wpc.wepolices.com'

const buildCommand =
  'cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build'

let config = loadConfig()

;(async function main() {
  if (!config) return
  // 正式版本发包
  if (config.isRelease) {
    // 打版本号
    await makeRelease()
    // 替换环境变量
    const content = replaceBuildEnv()
    // 打包
    execSync(buildCommand, { stdio: 'inherit' })
    // 恢复环境变量
    rollbackBuildEnv(content)

    if (config.upload) {
      // 上传包
      await UploadProject()
    } else {
      await PreviewProject()
    }
  } else if (config.prefix) {
    if (config.upload) {
      // 上传包
      await UploadProject()
    } else {
      await PreviewProject()
    }
  } else {
    /**
     * 测试版本发包
     */
    const content = replaceBuildEnv()
    // 打包
    execSync(buildCommand, { stdio: 'inherit' })
    // 恢复环境变量
    rollbackBuildEnv(content)

    if (config.upload) {
      // 上传包
      await UploadProject()
    } else {
      await PreviewProject()
    }
  }
})()

function UploadProject() {
  return upload({
    project: loadProject(),
    version: config.pkgVersion,
    desc: config.deployMsg,
    setting: {
      es6: true,
      minifyWXML: true,
      minifyWXSS: true
    },
    robot: config.robot
  })
}

function PreviewProject() {
  return preview({
    test: true,
    project: loadProject(),
    desc: config.deployMsg,
    setting: {
      es6: true,
      minifyWXML: true,
      minifyWXSS: true
    },
    robot: +config.robot + 10,
    // 返回二维码文件的格式 "image" 或 "base64"， 默认值 "terminal" 供调试用
    qrcodeFormat: 'terminal'
  })
}

function loadProject() {
  return new Project({
    appid: config.wxAppid,
    type: 'miniProgram',
    projectPath: path.posix.join(
      __dirname,
      `../dist/${config.prefix || 'build'}/mp-weixin`
    ),
    privateKeyPath: config.pskPath
  })
}

function loadConfig() {
  const pkg = require(path.posix.join(__dirname, '../package.json'))
  const wxAppid = process.env.VUE_APP_WXAPPID
  const pskPath = path.posix.join(__dirname, `./private.${wxAppid}.key`)
  if (!fs.existsSync(pskPath)) {
    return console.log(
      `💥${colors.red('miniprogram-ci private key is not load')}`
    )
  }

  const argv1 = loadArgv()
  const deployMsg = `包版本：【${pkg.version}】；包类型：【${
    argv1.isRelease ? '正式' : '测试'
  }】；服务端地址：【${
    !argv1.isRelease && argv1.prodServer ? '正式服' : '测试服'
  }】；备注：【${argv1.msg}】`

  return {
    wxAppid,
    pskPath,
    deployMsg,
    ...argv1,
    pkgVersion: pkg.version
  }
}

function loadArgv() {
  const argv = process.argv.slice(2)

  const flag = {
    // 上传项目路径
    prefix: '',
    msg: '',
    robotId: 1,
    isRelease: false,
    prodServer: false,
    upload: true,
    preview: false
  }

  // 发行版会更换.env配置自动打包(优先级最高)
  if (argv.includes('-release')) {
    flag.isRelease = true
  }

  if (!flag.isRelease && argv.includes('-only-deploy')) {
    flag.prefix = argv[argv.indexOf('-only-deploy') + 1]
  }

  if (!flag.isRelease && argv.includes('-prod-server')) {
    flag.prodServer = true
  }

  if (argv.includes('-msg')) {
    flag.msg = argv[argv.indexOf('-msg') + 1]
  }

  if (argv.includes('-preview')) {
    flag.preview = true
    flag.upload = false
  }

  if (argv.includes('-robotId')) {
    flag.robotId = +argv[argv.indexOf('-robotId') + 1]
  }

  return flag
}

function makeRelease() {
  return standardVersion({
    infile: 'CHANGELOG.md',
    silent: false
  }).then(() => {
    config = loadConfig()
    return null
  })
}

function replaceBuildEnv() {
  const envPath = path.posix.join(__dirname, '../.env.production')
  const content = fs.readFileSync(envPath, 'utf-8')

  fs.writeFileSync(
    envPath,
    `VUE_APP_PAAS_API_URL=${
      config.isRelease
        ? PROD_SERVER_API
        : config.prodServer
        ? DEV_SERVER_API
        : PROD_SERVER_API
    }`
  )

  return content
}

function rollbackBuildEnv(content) {
  const envPath = path.posix.join(__dirname, '../.env.production')
  fs.writeFileSync(envPath, content)
}
